; MBOOT100.A86 - MBOOT for the DEC PC100 Rainbow microcomputer
; M. J. Mellinger, St. Louis RCPM 4/10/83
;
FALSE	EQU	0
TRUE	EQU	NOT FALSE
;
BASE	EQU	0
;
EXITCHR	EQU	06H	;CTL-F TO EXIT TERM MODE TO CP/M
ESC	EQU	01H	;CTL-A TO EXIT TERM MODE TO FILE RCVE
;
FASTCLK	EQU	TRUE	; VT180 HAS 4 MHZ CLOCK
;
;
; modem definitions
modctlp	equ	042h
modctl2	equ	002h
modsndb	equ	4
modsndr	equ	4
modrcvb	equ	1
modrcvr	equ	1
moddatp	equ	040h
baudrp	equ	006h
;
;
;
ERRLIM	EQU	10
;
SOH	EQU	1
EOT	EQU	4
ACK	EQU	6
NAK	EQU	15H
CAN	EQU	18H
LF	EQU	10
CR	EQU	13
;
FCB	EQU	BASE+5CH
;
	cseg
;	ORG	BASE+100H
;
	cld
	CALL	INITADR
	CALL	ILPRT
	DB	'MBOOT-Rainbow as of '
	DB	'4/10/83',CR,LF,0
	mov	al,fcb+1
	cmp	al,' '
	JNZ	TERMI
	CALL	ILPRT
	DB	'++NO FILE NAME SPECIFIED++',CR,LF,0
	JMP	EXIT
;
TERMI:	CALL	INITMOD
	IN	AL,MODDATP
	IN	AL,MODDATP
	CALL	ILPRT
	DB	CR,LF,'Terminal mode',CR,LF
	DB	'CTL-F exits to CP/M, CTL-A starts file transfer.'
	DB	CR,LF,0
;
TERM:	CALL	STAT
	JZ	TERML
	CALL	KEYIN
	cmp	al,exitchr
	JNZ	TERM01
	JMP	EXIT
TERM01:
	cmp	al,esc
	jz	rcvfil
	OUT	MODDATP,AL
TERML:	IN	AL,MODCTLP
	AND	AL,MODRCVB
	CMP	AL,MODRCVR
	JNZ	TERM
	IN	AL,MODDATP
	AND	AL,7FH
	CALL	TIPE
	JMP	TERM
;
RCVFIL:	CALL	ERASFIL
	CALL	MAKEFIL
	CALL	ILPRT
	DB	'FILE OPEN, READY TO RECEIVE',CR,LF,0
;
RCVLP:	CALL	RCVSECT
	JC	RCVEOT
	CALL	WRSECT
	CALL	INCRSNO
	CALL	SENDACK
	JMP	RCVLP
;
RCVEOT:	CALL	WRBLOCK
	CALL	SENDACK
	CALL	CLOSFIL
	CALL	ERXIT
	DB	CR,LF,'TRANSFER COMPLETE$'
;
RCVSECT:
	Xor	Al,al
	mov	errct,al
;
RCVRPT:	Mov	CH,10
	CALL	RECV
	JC	RCVSERR
	cmp	al,soh
	jz	rcvsoh
	or	al,al
	jz	rcvrpt
	cmp	al,eot
	STC
	jnz	rcvserr
	ret
;
RCVSERR:
	mov	CH,1
	CALL	RECV
	JNC	RCVSERR
	mov	al,nak
	CALL	SEND
	MOV	AL,ERRCT
	INC	AL
	MOV	ERRCT,AL
	CMP	AL,ERRLIM
	JC	RCVRPT
;
RCVSABT:
	CALL	CLOSFIL
	CALL	ERXIT
	DB	'++UNABLE TO RECEIVE BLOCK'
	DB	CR,LF,'++ABORTING++$'
;
RCVSOH:	MOV	CH,1
	CALL	RECV
	JC	RCVSERR
	MOV	DH,AL
	MOV	CH,1
	CALL	RECV
	JC	RCVSERR
	NOT	AL
	CMP	AL,DH
	JZ	RCVDATA
	JMP	RCVSERR
;
RCVDATA:
	MOV	AL,DH
	MOV	RCVSNO,AL
	MOV	CL,0
	MOV	BX,OFFSET BASE+80H
;
RCVCHR:	MOV	CH,1
	CALL	RECV
	JC	RCVSERR
	MOV	DS: BYTE PTR [BX],AL
	INC	BL
	JNZ	RCVCHR
	MOV	DH,CL
	MOV	CH,1
	CALL	RECV
	JC	RCVSERR
	CMP	DH,AL
	JZ	RCVCHR01
	JMP	RCVSERR
RCVCHR01:
	MOV	CH,RCVSNO
	MOV	AL,SECTNO
	CMP	CH,AL
	JZ	RECVACK
	INC	AL
	CMP	CH,AL
	JNZ	ABORT
	RET
;
RECVACK:
	CALL	SENDACK
	JMP	RCVSECT
;
SENDACK:
	MOV	AL,ACK
;
SEND:	PUSH	AX
	ADD	CL,AL
SENDW:	IN	AL,MODCTLP
	AND	AL,MODSNDB
	CMP	AL,MODSNDR
	JNZ	SENDW
	POP	AX
	OUT	MODDATP,AL
	RET
;
ABORT:
;
ABORTL:	MOV	CH,1
	CALL	RECV
	JNC	ABORTL
	MOV	AL,CAN
	CALL	SEND
;
ABORTW:	MOV	CH,1
	CALL	RECV
	JNC	ABORTW
	MOV	AL,' '
	CALL	SEND
	CALL	ERXIT
	DB	'MBOOT PROGRAM CANCELLED$'
;
INCRSNO:
	INC	SECTNO
	RET
;
ERASFIL:
	MOV	DX,OFFSET FCB
	MOV	CL,17
	CALL	BDOS
	INC	AL
	JNZ	ERAS01
	RET
ERAS01:
	CALL	ILPRT
	DB	'++FILE EXISTS, TYPE Y TO ERASE:',0
	CALL	KEYIN
	PUSH	AX
	CALL	TIPE
	CALL	CRLF
	POP	AX
	AND	AL,5FH
	CMP	AL,'Y'
	JZ	ERAS02
	JMP	MXIT
ERAS02:
	MOV	DX,OFFSET FCB
	MOV	CL,19
	JMP	BDOS
;
MAKEFIL:
	MOV	DX,OFFSET FCB
	MOV	CL,22
	CALL	BDOS
	INC	AL
	JZ	MAKE01
	RET
MAKE01:
	CALL	ERXIT
	DB	'++ERROR - CAN''T MAKE FILE',CR,LF
	DB	'++DIRECTORY MUST BE FULL$'
;
CLOSFIL:
	MOV	DX,OFFSET FCB
	MOV	CL,16
	CALL	BDOS
	INC	AL
	JZ	CLOS01
	RET
CLOS01:
	CALL	ERXIT
	DB	'++CAN''T CLOSE FILE$'
;
WRSECT:	MOV	BX,SECPTR
	XCHG	BX,DX
	MOV	BX,OFFSET 80H
	CALL	MOVE128
	XCHG	BX,DX
	MOV	SECPTR,BX
	MOV	AL,SECINBF
	INC	AL
	MOV	SECINBF,AL
	CMP	AL,16
	JZ	WRBLOCK
	RET
;
WRBLOCK:
	MOV	AL,SECINBF
	OR	AL,AL
	JNZ	WRBL01
	RET
WRBL01:
	MOV	CL,AL
	MOV	DX,OFFSET DBUF
;
DKWRLP:	PUSH	BX
	PUSH	DX
	PUSH	CX
	MOV	CL,26
	CALL	BDOS
	MOV	DX,OFFSET FCB
	MOV	CL,21
	CALL	BDOS
	POP	CX
	POP	DX
	POP	BX
	OR	AL,AL
	JNZ	WRERR
	MOV	BX,OFFSET 80H
	ADD	BX,DX
	XCHG	BX,DX
	DEC	CL
	JNZ	DKWRLP
	XOR	AL,AL
	MOV	SECINBF,AL
	MOV	BX,OFFSET DBUF
	MOV	SECPTR,BX
RSDMA:
	MOV	DX,OFFSET 80H
	MOV	CL,26
	JMP	BDOS
;
WRERR:	CALL	RSDMA
	CALL	ILPRT
	DB	'++ERROR WRITING FILE',CR,LF,0
	JMP	ABORT
;
RECV:	PUSH	DX
;
	IF	FASTCLK
	MOV	AL,CH
	ADD	AL,AL
	MOV	CH,AL
	ENDIF
;
MSEC:	MOV	DX,15000
;
MWTI:	
	IN	AL,MODCTLP
	AND	AL,MODRCVB
	CMP	AL,MODRCVR
	JZ	MCHAR
	DEC	DL
	JNZ	MWTI
	DEC	DH
	JNZ	MWTI
	DEC	CH
	JNZ	MSEC
	POP	DX
	STC
	RET
;
MCHAR:	IN	AL,MODDATP
	POP	DX
	ADD	CL,AL
	OR	AL,AL
	RET
;
INITADR:
	RET
;
;
INITMOD:
;
	MOV	AL,24
	OUT	MODCTLP,AL
	MOV	AL,4
	OUT	MODCTLP,AL
	MOV	AL,68
	OUT	MODCTLP,AL
	MOV	AL,1
	OUT	MODCTLP,AL
	MOV	AL,0
	OUT	MODCTLP,AL
	MOV	AL,3
	OUT	MODCTLP,AL
	MOV	AL,193
	OUT	MODCTLP,AL
	MOV	AL,5
	OUT	MODCTLP,AL
	MOV	AL,234
	OUT	MODCTLP,AL
	MOV	AL,0
	OUT	MODCTLP,AL
	MOV	AL,00		; CLEAR BITS TO SET DTR
	OUT	MODCTL2,AL	; OUT TO COMM CONTROL REGISTER
	RET
;
;
EXIT:	MOV	CL,0
	mov	dl,0
;
BDOS:	PUSH	ES	; PRESERVE ES
	INT	224	; CPM-86 BDOS CALL
	POP	ES
	RET
;
CRLF:	MOV	AL,CR
	CALL	TIPE
	MOV	AL,LF
;
TIPE:	PUSH	CX
	PUSH	DX
	PUSH	BX
	PUSH	SI
	AND	AL,07FH
	MOV	DL,AL
	MOV	CL,DCONIO
	CALL	BDOS
	POP	SI
	POP	BX
	POP	DX
	POP	CX
	RET
;KEYBOARD STATUS
Stat:	mov	cl,DCONIO
	mov	dl,0FEH
	call	bdos
	OR AL,AL	;0 => NOT READY
	RET
;
;KEYBOARD INPUT
;
keyin:	mov	cl,DCONIO
	mov	dl,0ffh
	call	bdos
	or	al,al
	jz	keyin
	ret
;
ILPRT:	POP	SI
	XCHG	BX,SI
	PUSH	SI
;
ILPLP:	MOV	AL,CS: byte ptr [BX]
	OR	AL,AL
	JZ	ILPRET
	CALL	TIPE
	INC	BX
	JMP	ILPLP
;
ILPRET:	INC	BX
	POP	SI
	XCHG	BX,SI
	PUSH	SI
	RET
;
ERXIT:	POP	DX
	PUSH	DS
	MOV	AX,CS
	MOV	DS,AX
	MOV	CL,9
	CALL	BDOS
	POP	DS
;
MXIT:	CALL	ILPRT
	DB	CR,LF,'Don''t forget to disconnect modem'
	DB	CR,LF,0
	JMP	EXIT
;
MOVE128:
	MOV	CH,128
;
MOVE:	MOV	AL,ds:BYTE PTR [BX]
	XCHG	BX,DX
	MOV	ds: byte ptr [BX],AL
	XCHG	BX,DX
	INC	BX
	INC	DX
	DEC	CH
	JNZ	MOVE
	RET
endcs	equ	$
;
	dseg
;	org	offset endcs
	ORG	100H
RCVSNO	DB	0
SECTNO	DB	0
ERRCT	DB	0
EOFLG	DB	0
SECPTR	DW	DBUF
SECINBF	DB	0
DBUF	RB	16*128
;
;bdos equates
DCONIO	EQU	6
CONST	EQU	11
	END
